/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package windowgravitydemo;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;
import javax.swing.JFrame;

/**
 *
 * @author PHU QUOC
 */
public class MainFrame extends JFrame implements MouseListener, KeyListener, Runnable{
    private MainPanel mainpanel;
    private boolean isrunning;
    private Dimension screensize;
    private Toolkit toolkit;
    private Thread mainthread;
    private double m_current_position_x;
    private double m_current_position_y;
    private double m_init_position_x;
    private double m_init_position_y;
    private double m_current_velocity_x;
    private double m_current_velocity_y;
    private double m_init_velocity_x;
    private double m_init_velocity_y;
    private double m_release_time;
    private int m_bound_rect_x;
    private int m_bound_rect_y;
    private int m_bound_rect_width;
    private int m_bound_rect_height;
    private double m_elastic;
    private double m_friction;
    private int m_object_radius;
    private boolean m_need_check_bound;
    private final int M_DEFAULT_RADIUS = 100;
    private final double M_DEFAULT_ELASTIC =  1.0;//default 0.95
    private final double M_DEFAULT_FRICTION = 1.0;//default 1.0
	private boolean is_going_down;
	private boolean is_going_left;
    private Random m_random;
    public MainFrame(){
        toolkit = Toolkit.getDefaultToolkit();
        screensize = toolkit.getScreenSize();
        setBounds(screensize.width/2, screensize.height/2, M_DEFAULT_RADIUS*2, M_DEFAULT_RADIUS*2);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setAlwaysOnTop(true);
        setResizable(false);
    }
    public void initialize(){
        
        mainpanel = new MainPanel();
        mainpanel.initialize();
        setContentPane(mainpanel);
        m_need_check_bound = true;
        m_release_time = System.currentTimeMillis();
        m_random = new Random();
        
        int ini_position_x = screensize.width/2;
        int ini_position_y = screensize.height/2;
        int ini_power = m_random.nextInt(150) - 50;
        double ini_angle_in_radian = Math.toRadians(m_random.nextInt(360));


        m_current_position_x = m_init_position_x = ini_position_x;
        m_current_position_y = m_init_position_y = ini_position_y;
        m_current_velocity_x = m_init_velocity_x = ini_power*Math.cos(ini_angle_in_radian);
        m_current_velocity_y = m_init_velocity_y = ini_power*Math.sin(ini_angle_in_radian);
        setBoundRect(0, 0, screensize.width, screensize.height);        
        m_object_radius = M_DEFAULT_RADIUS;
		is_going_down = true;
		is_going_left = false;
        m_elastic = M_DEFAULT_ELASTIC;
        m_friction = M_DEFAULT_FRICTION;        
        addKeyListener(this);
        addMouseListener(this);        
        mainthread = new Thread(this);
        isrunning = true;
        mainthread.start();        
    }

    public void setBoundRect(int rect_x, int rect_y, int rect_width, int rect_height){
        m_bound_rect_x = rect_x;
        m_bound_rect_y = rect_y;
        m_bound_rect_width = rect_width;
        m_bound_rect_height = rect_height;
        m_need_check_bound = true;
    }
    
    public void run(){
        while(isrunning){
            try{
                Thread.sleep(10);
            }
            catch(Exception e){}

            double elapsed_time = (System.currentTimeMillis() - m_release_time)*0.01;
            double distance_position_x = (m_init_velocity_x * elapsed_time);//new_x = v0x * time;
            double distance_position_y = (m_init_velocity_y * elapsed_time + 0.5 * (-9.8) * elapsed_time * elapsed_time);//new_y = v0y * time + 1/2 * gravity(-9.8) * time * time;

            //recalculate velocity
    //        m_current_velocity_x = m_velocity_init_x;//no change with time, no need to compile this line
            m_current_velocity_y = m_init_velocity_y + (-9.8) * elapsed_time;// vt = v0t + gravity*time
        if(m_init_velocity_x < 0)
            is_going_left = true;
        else if(m_init_velocity_x > 0)
            is_going_left = false;
        if(m_current_velocity_y < 0)
            is_going_down = true;        

            m_current_position_x = m_init_position_x + distance_position_x;
            m_current_position_y = m_init_position_y - distance_position_y;//vi chieu duong huong xuong nen phai tru

            //bound check
            if(m_need_check_bound){
                //down
                if((m_current_position_y + m_object_radius) >= (m_bound_rect_y + m_bound_rect_height)){
//                    m_current_position_y = (m_bound_rect_y + m_bound_rect_height) - m_object_radius;
                if(is_going_down){
                    m_init_velocity_y = -m_current_velocity_y * m_elastic / m_friction;
                    is_going_down = false;
                }
                    m_init_velocity_x = m_init_velocity_x * m_elastic / m_friction;
                    m_init_position_x = m_current_position_x;
                    m_init_position_y = m_current_position_y;
                    m_release_time = System.currentTimeMillis();
                }
                //left
                if((m_current_position_x - m_object_radius) <= m_bound_rect_x){
                    m_init_velocity_y = m_current_velocity_y;
                if(is_going_left){
                    m_current_velocity_x = m_init_velocity_x = -m_init_velocity_x * m_elastic / m_friction;
                    is_going_left = false;
                }
                    m_init_position_x = m_current_position_x;
                    m_init_position_y = m_current_position_y;
                    m_release_time = System.currentTimeMillis();
                }
                //right
                if((m_current_position_x + m_object_radius) >= (m_bound_rect_x + m_bound_rect_width)){
                    m_init_velocity_y = m_current_velocity_y;
                if(!is_going_left){
                    m_current_velocity_x = m_init_velocity_x = -m_init_velocity_x * m_elastic / m_friction;
                    is_going_left = true;
                }
                    m_init_position_x = m_current_position_x;
                    m_init_position_y = m_current_position_y;
                    m_release_time = System.currentTimeMillis();
                }
            }            
            setLocation((int)m_current_position_x - m_object_radius, (int)m_current_position_y - m_object_radius);
        }
    }

    public void keyTyped(KeyEvent e) {

    }

    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_ESCAPE)
            System.exit(0);
    }

    public void keyReleased(KeyEvent e) {

    }

    public void mouseClicked(MouseEvent e) {
        
    }

    public void mousePressed(MouseEvent e) {
    }

    public void mouseReleased(MouseEvent e) {

    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }
}
